package cn.steam.foo.service.impl;

import cn.steam.foo.dao.UserDao;
import cn.steam.foo.entity.User;
import cn.steam.foo.model.UserVO;
import cn.steam.foo.service.UserService;
import cn.steam.foo.util.CopyUtils;
import cn.steam.foo.util.RedisUtil;
import cn.steam.foo.util.Riven;
import cn.steam.foo.util.lock.KLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.core.task.TaskExecutor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author zhang jintao on 2022/05/11
 **/
@Service
@CacheConfig(cacheNames = "fuck")
public class UserServiceImpl implements UserService {

    private final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
    private static final Map<String, Double> taskMap = new HashMap<>();

    @Autowired
    UserDao userDao;
    @Autowired
    KafkaTemplate<String, String> kafkaTemplate;
    @Autowired
    RedisTemplate<String, String> redisTemplate;
    @Autowired
    RedisUtil redisUtil;
    @Autowired
    TaskExecutor taskExecutor;

    @Value("${virtual.coupon.origin.relation:{4:[13,14,15,16,17,18,19],2:[4]}}")
    private String originCouponIdRelation;


    @Override
    @Cacheable(key = "#id")
    @KLock(key = "#id")
    public UserVO getById(Long id) {
        return CopyUtils.copy(userDao.findById(id).orElse(null), UserVO.class);
    }

    @Override
    @CacheEvict(key = "#id")
    @Transactional(rollbackFor = Throwable.class)
    public void delete(Long id) {
        userDao.deleteById(id);
        kafkaTemplate.send("topic_foo", String.valueOf(id), "删除用户:" + id);
    }


    @Override
    public String importUsers(Integer num) {
        String task = UUID.randomUUID().toString();
        taskExecutor.execute(() -> {
            this.saveAll(task, num);
        });
        return task;
    }

    @Override
    public Double getTask(String sn) {
        return taskMap.get(sn);
    }

    @Override
    @Transactional
    @Async
    public void saveAll(String task, Integer num) {
        taskMap.put(task, 0.0);
        int size = 10;
        double complete = 0.0;
        for (int i = 0; i < num / 10; i++) {
            ArrayList<User> users = new ArrayList<>();
            for (int j = 0; j < size; j++) {
                String englishName = Riven.englishName();
                int age = Riven.age();
                User user = User.builder()
                        .name(Riven.name())
                        .age(age)
                        .address(Riven.city())
                        .englishName(englishName)
                        .email(Riven.email(englishName))
                        .idCard(Riven.idCard(age))
                        .phone(Riven.telephone()).build();
                users.add(user);
            }
            userDao.saveAll(users);
            complete += size;
            taskMap.put(task, complete / num);
            logger.info("完成任务:complete:{}", complete);
        }
    }

    public String fuck() {
        return "originCouponIdRelation";
    }
}
